Coding Standards

Please read these documents from these websites:

  1. MSDN - ".NET Framework General Reference: Naming Guidelines"
    http://msdn.microsoft.com/library/en-us/cpgenref/html/cpconnamingguidelines.asp
  2. Philips Medical Systems - "Coding Standard: C#"
    http://www.tiobe.com/index.htm?standards
  3. FxCop - "Design Guidelines: Naming Rules"
    http://www.gotdotnet.com/team/fxcop/Docs/Rules.html
  4. Lance Hunt - "CSharp_Coding_Standards"
    http://weblogs.asp.net/lhunt

Terms

Capitalization Styles

c = camel Case
P = Pascal Case
_ = Prefix with _Underscore

Identifier Public Protected Internal Private Notes
Project File P       Match Assembly & Namespace.
Source File P       Match contained class.
Other Files P       Apply where possible.
Namespace P       Partial Project/Assembly match.
Class or Structure P P P P Add suffix of subclass.
Interface P P P P Prefix with a capital .
Generic Class P P P P Use or as Type identifier.
Method / Function P P P P Use a Verb or Verb-Object pair.
Property P P P P Do not prefix with or .
Field P P P _c Only use Private fields. No Hungarian Notation!
Constant P P P _c  
Static Field P P P _c Only use Private fields.
Enumeration P P P P Options are also Pascal Case.
Delegate P P P P  
Event P P P P  
Variable P   c c  
Inline Variable       c Avoid single-character and enumerated names.
Parameter       c

To avoid confusion and guarantee cross-language interoperation, follow these rules regarding the use of abbreviations:

Notes about ID vs. Id

Notes about "Direcotry" and "Folder"
  • Directory – It is a container for files and other directories. Directory has permanent physical location on the hard drive or other storage medium.
  • Folder – It is an interface and container for a collection of objects. Folder can be stored on disk, in memory by a DLL, in the Registry and may contain items that are not true files but are virtual objects. These are folders: "My Computer", "Control Panel", "Dial-Up Networking", "Network Neighbourhood", "Printers", "Fonts" and the "Recycle Bin"
  • In Windows all directories are folders but not all folders are directories.
  • "Folders" includes everything that we used to call a "directory" plus some abstract objects.
  • Better to use this :
        System.IO.DirectoryInfo[] directories;
        directories = new System.IO.Directory.GetDirectories("C:\\");
        System.IO.DirectoryInfo directory = directories[0];
    Than this :
        System.IO.DirectoryInfo[] folders;

Links

Code Style

File Organization

Source files should contain only one public type, although multiple internal classes are allowed. Source files should be given the name of the public class in the file. Directory names should follow the namespace for the class. For example, I would expect to find the public class “System.Windows.Forms.Control” in “System\Windows\Forms\Control.cs”…

Classes member should be alphabetized, and grouped into sections (Fields, Constructors, Properties, Events, Methods, Private interface implementations, Nested types). Using statements should be inside the namespace declaration.

namespace MyNamespace
{
    using System;
    public class MyClass : IFoo
    {
        // Fields.
        int foo;
        // Constructors.
        public MyClass() { … }
        // Properties.
        public int Foo { get { … } set { … } }
        // Events.
        public event EventHandler FooChanged { add { … } remove { … } }
        // Methods.
        void DoSomething() { … }
        void FindSomethind() { … }

        // Private interface implementations.
        void IFoo.DoSomething() { DoSomething(); }

        // Nested types.
        class NestedType { … }
    }
}

Rules, that doesn't correspond with the Microsoft rules:

JavaScript

For JavaScript use same coding standard as for C#.
Best coding practice is:
"Turn on XML documentation" and "Format things the way Visual Studio (2005) does".

JavaScript - Class Example

 

// Create array with some Data.
var array = new Array();
array.push("one");
array.push("two");
// Create class.
var class1 = new Class1();
// Bind function to event.
class1.OnDataBound = function(sender, e){ alert("Data DataSource["+e.Data+"] was binded to "+sender.Type); };
// Set data source.
class1.DataSource = array;
// Bind Data. 
class1.DataBind();

---------------------------------------------------------------

System.EventArgs = function(name){
	this.Name = "";
	this.Type = "System.EventArgs";
	//---------------------------------------------------------
	// METHOD: ToString
	//---------------------------------------------------------
	this.ToString = function(){
		var results = new String();
		for (var property in this){
			var skip = false;
			skip = skip || (property == "InitializeClass");
			skip = skip || (property == "ToString");
			if (!skip) results += property+"='"+this[property]+"';";	
		}
		results = "e["+results+"]";
		return results;
	}

// Optional: this allows automatic conversation of this object to string by JavaSript.
// this.toString = this.ToString; //--------------------------------------------------------- // INIT: InitializeClass //--------------------------------------------------------- this.InitializeClass = function(){ this.Name = name ? name : new String; } this.InitializeClass(); } Namespace1.Namespace2.Class1 = function(id,target,value){ this.Type = "Namespace1.Namespace2.Class1"; //--------------------------------------------------------- // PROPERTIES: Public //--------------------------------------------------------- this.id = new String; this.Target = null; this.DataSource = null this.Node = null; //--------------------------------------------------------- // PROPERTIES: Private //--------------------------------------------------------- // This property is required. var me = this; //--------------------------------------------------------- // HANDLERS / PUBLIC EVENTS: //--------------------------------------------------------- // Function which runs external function if it was attached.
this.RiseEvent = function(e){ if (this[e.Name]){ this[e.Name](this,e) } } //--------------------------------------------------------- // Assign 'null' to event handlers. this.OnInit = null; this.OnDataBound = null this.OnClick = null; //--------------------------------------------------------- // METHOD: DataBind //--------------------------------------------------------- this.DataBind = function(){ // Bind array to Node. var text = new String; for (var i = 0; i < this.DataSource.length; i++){ text += this.DataSource[i]+","; } this.Node.innerHTML = "Data: "+text+" - Click Here."; var e = new System.EventArgs("OnDataBound"); // Always: set parameter first time with quotes. // Get parameter value with e.Data reference. e["Data"] = this.DataSource; this.RiseEvent(e); } //--------------------------------------------------------- // EVENT PRIVATE: onClick //--------------------------------------------------------- this.onClick = function(sender, e){ sender.Node.innerHTML = "Clicked! Wait..."; // Display content of node after 1 second. // We need to use 'me' otherwise we will loose reference to object. setTimeout(function(){ me.Node.innerHTML += "Done."; },1000); } //--------------------------------------------------------- // INIT: InitializeInterface //--------------------------------------------------------- this.InitializeInterface = function(sender, e){ this.Node = this.Target.createElement("div"); this.Node.style.position = "absolute"; this.Node.style.top = "10px"; this.Node.style.left = "10px"; this.Node.style.cursor = "pointer"; this.Node.style.padding = "8px"; this.Node.style.border = "solid 1px #000000"; this.Node.style.backgroundColor = "#d0ffd0"; this.Node.innerHTML = "no data"; this.Target.body.appendChild(this.Node); } //--------------------------------------------------------- // INIT: InitializeEvents //--------------------------------------------------------- this.InitializeEvents = function(sender, e){ this.Node.onclick = function(){ me.onClick(me, new System.EventArgs("OnClick")) };
} //--------------------------------------------------------- // INIT: InitializeClass //--------------------------------------------------------- this.InitializeClass = function(){ // By default use current document. this.Target = target ? target : document; // Set submited values or default values. this.id = id ? id : ""; // Create HTML Element. this.InitializeInterface(this); // Attach events.; this.InitializeEvents(this); // Rise init event. this.RiseEvent(new System.EventArgs("OnInit")); } this.InitializeClass.apply(this,arguments); } Using: var MyObject = null; Group1.Init = function(){ MyObject = new Namespace1.Namespace2.Class1("testId"); // Attach function to event. Replace "On" with "_"; MyObject.OnDataBound = Group1.MyObject_DataBound; } Group1.MyObject_OnDataBound = function(sender, e){ // Do some stuff here then data is bounded. } Notes:

JavaScript - Naming

Naming

Use C# coding standards for JavaScript

  1. Use same casing as in C#. For Example:
        // Use Pascal casing for public parameters and methods inside classes.
        Right: this.ToString = function(){...}
        Wrong: this.toString = function(){...}
        // Use Camel casing for local private variables inside classes.
        Right: var someVariable = new String;
        Wrong
    : var SomeVariable = new String;
  2. Always declare types. If type is unknown then use Object type.
        var unknownVariable = new Object;
  3. Use camel casing for local variable names and function arguments
    var someNumber;
    function SomeFunction(someText){}
  4. Name object functions using verb-object pairs, such as:
    this.ShowDialog = function(){}
  5. Functions with return values should have a name describing the value returned, such as:
    function GetObjectState(){}
  6. Use descriptive variable names.
    1. Avoid single character variable names, such as "i" or "t". Use index or temp instead.
      For loops you can use 3 letter indexes "idx", "dbx".
    2. Do not abbreviate words (such as num instead of number).
  7. Indent comments at the same level of indentation as the code you are documenting.
  8. All public comments should pass spell checking.
  9. All object variables should be declared at the top, with one line separating them from the functions.
  10. function SomeObject(){
        var someVariable;
        this.SomeFunction = function(){}
    }
  11. Declare a local variable as close as possible to its first use.

Coding Practice

  1. Avoid putting multiple unrelated functions in the same include file.
  2. Give include files the .asp suffix if it contains sensitive data. In this case script data will be hidden from client.
  3. Try to use same scripts on client side and server side. Add .js suffix to these files and use this template:
    <!--//--><%
    //=============================================================================
    // You can include this script on both sides - server and client:
    // Server: <!-- #INCLUDE FILE="SharedScript.js" -->
    // Client: <script type="text/javascript" src="SharedScript.js"></script>
    //-----------------------------------------------------------------------------
    // Warning: Be careful about what code you include in such way. Since the  code
    // will be passed to the client side as simple text, your code can be  seen  by
    // anyone who wants. Never do this with  scripts  which  contain  any  kind  of
    // passwords, database connection strings, or SQL queries.
    //-----------------------------------------------------------------------------
    ...
    //-----------------------------------------------------------------------------
    //%>
  4. Avoid files with more than 500 lines (excluding machine-generated code).
  5. Avoid functions with more than 25 lines.
  6. Avoid functions with more than 5 arguments. Use structures/objects/classes for passing multiple arguments.
  7. Do not manually edit machine-generated code.
  8. Avoid comments that explain the obvious. Code should be self explanatory. Good code with readable variables and function names should not require comments.
  9. Document only operational assumptions, algorithm insights and so on.
  10. Avoid method-level documentation.
    1. Use extensive external documentation for API documentation.
    2. Use method-level comments only as tool tips for other developers.
  11. Avoid code that relies on a page web program running from a particular location.
  12. Minimize code in directly called asp pages. Use included asp pages instead to contain business logic.
  13. Avoid function calls in Boolean conditional statements. Assign into local variablesand check on them:
    function isEverythingOk(){}
    //Avoid:
    if (isEverythingOk()){}
    //Instead:
    var IsOk = isEverythingOk();
    if (IsOk){}
  14. Always use zero-based arrays.
  15. Never hardcode strings that will be presented to the users in the directly called asp page or the asp pages with business logic. Use resources instead.
  16. Never hardcode strings that might change based on deployment such as connection strings in the directly called asp page or the asp pages with business logic.
  17. Use application logging and tracing.
  18. Always have a default case in the switch statement that is handled as an error.
  19. Store settings inside XML files. Try to use Web.config if available (in this case you need to create JavScript class to get values from this file).

Useful Links

Event compatibility tables information for cross Browser development:
http://www.quirksmode.org/js/events_compinfo.html

Type Conversions:
http://www.jibbering.com/faq/faq_notes/type_convert.html

JavaScript - Performace

Arrays

The conventional way of coding a for loop to process an array lis like this:

for (var i = 0; i < myArray.length; i++) {...

The problem with this is that evaluation of the length of the array using myArray.length has to be performed every time around the loop. These two methods are about 50% faster (because we are creating variable that holds that value):

var j = myArray.length;
for (var i = 0; i < j; i++) {...

or reverse:

for (var i = myArray.length-1; i > -1; i--) {...

Note: this can be replace by this:
var i = myArray.length; while(i--){...